Skip to content

Conversation

@Linqa2
Copy link
Owner

@Linqa2 Linqa2 commented Jan 9, 2026

Problem

Calling retrieveConnectedPeripherals() or other connection methods multiple times for the same CBPeripheral would create new ConnectedPeripheral wrapper instances, causing:
• Delegate overwrite: Each new wrapper set cbPeripheral.delegate, breaking previous wrappers
• Zombie sessions: Old wrappers stopped receiving callbacks (notifications, reads, writes)
• Memory leaks: Multiple wrappers tracking the same peripheral

Solution

Implemented an identity map pattern with weak references to ensure at most one live wrapper per CBPeripheral.identifier:

• Added WeakBox<T> helper for storing weak references
• Added peripheralWrappers: [UUID: WeakBox<ConnectedPeripheral>] identity map
• Created getOrCreateWrapper(for:) to serve as single point of wrapper creation
• Replaced all 4 direct ConnectedPeripheral(...) instantiations with getOrCreateWrapper
• Added automatic cleanup of dead weak references
• Added detection/logging for duplicate CBPeripheral instances

@Linqa2 Linqa2 merged commit 565c4ea into main Jan 9, 2026
1 check passed
@Linqa2
Copy link
Owner Author

Linqa2 commented Jan 9, 2026

@hinathan
Hey! This PR attempts to implement idempotent behavior for peripheral sessions, so repeated calls should behave more consistently.

I’ve only run a quick regression test so far, so I’d really appreciate it if you could take a look and let me know whether this actually addresses the issue you were seeing. Thanks!

@hinathan
Copy link
Contributor

hinathan commented Jan 9, 2026

👍🏻 This works with my current code and one device, will have a chance to try with more hardware tomorrow.

@Linqa2 Linqa2 deleted the peripheral_wrapper_identity_map branch January 11, 2026 03:13
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Ensure idempotent wrapper identity for CBPeripheral across retrieve / connect paths

3 participants